package gestorvideoclub;

/**
 *
 * @author JAVA
 */
import gestorvideoclub.enumeraciones.*;
import gestorvideoclub.jdbc.*;
import gestorvideoclub.util.*;
import java.util.*;
import java.util.regex.Pattern;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import javax.management.timer.Timer;


/** Subclase de Usuario q hereda todo */
public class Cliente extends Usuario {

    private double saldo;
    private int NumProdAlqActual = 0;
    private static int NumMaxProducto;
    private Date FechaNacimiento;
    private Franquicia franquicia;

    static {
        NumMaxProducto = 5;
    }
/**Constructor por defecto*/

    public Cliente() {
    }
/**Constructor por parametros*/

    public Cliente(String nombre, String apellidos, String DNI, String contrasenya, String telefono,
            double saldo, Date FechaNacimiento, Rol rol) {
        super(nombre, apellidos, DNI, contrasenya, telefono, rol);
        this.saldo = saldo;
        this.NumProdAlqActual = 0;
        this.FechaNacimiento = new Date();//Esto hay que cambiarlo

    }
    /** Get y Set*/

    public Date getFechaNacimiento() {
        return FechaNacimiento;
    }

    public void setFechaNacimiento(Date FechaNacimiento) {
        this.FechaNacimiento = FechaNacimiento;
    }

    public static int getNumMaxProducto() {
        return NumMaxProducto;
    }

    public static void setNumMaxProducto(int NumMaxProducto) {
        Cliente.NumMaxProducto = NumMaxProducto;
    }

    public int getNumProdAlqActual() {
        return NumProdAlqActual;
    }

    public void setNumProdAlqActual(int NumProdAlqActual) {
        this.NumProdAlqActual = NumProdAlqActual;
    }

    public double getSaldo() {
        return saldo;
    }

    public void setSaldo(double saldo) {
        this.saldo = saldo;
    }


     /* Sobreescribir la presentacion de cliente*/
    @Override
    public String toString() {
        String cad = "\nNombre y apellidos: "+this.getNombre()+" "+this.getApellidos()+"\nDNI: "+this.getDNI()+"\nTelefono: "+this.getTelefono();
               cad += "\nFecha de nacimiento: "+UtilFecha.fechaMostrar(this.getFechaNacimiento());
               cad += "\nSaldo: " + this.getSaldo() + "\nNúmero Producto/s alquilado actualmente: "+this.getNumProdAlqActual();
               cad += "\nNumero Maximo de producto para alquilar: "+getNumMaxProducto();
               cad += "\nEstado cliente: " + this.getEstadoUsuario() + "\n";

               return cad;
    }

 @Override
    public void altaUsuario() {
        String texto = null;
        boolean correcto = false;
        Date fecha;

        Cliente cliente = new Cliente();

        do{
            System.out.print("Nombre del Cliente: ");
            texto = introduceDatos.introduceString();
            if(texto.length()>0){
                cliente.setNombre(texto);
                correcto = true;
            }
            else{
                System.out.println("[!] Error el nombre no puede ser vacío");
            }

        }while(!correcto);

        correcto = false;
        do{
            System.out.print("Apellidos del Cliente: ");
            texto = introduceDatos.introduceString();
            if(texto.length()>0){
                cliente.setApellidos(texto);
                correcto = true;
            }
            else{
                System.out.println("[!] Error los apellidos no puede ser vacío");
            }
            
        }while(!correcto);

        correcto = false;
        do{
            System.out.print("DNI del Cliente: ");
            texto = introduceDatos.introduceString();

            if(texto.length()>0 && texto.length()<=8){
                cliente.setDNI(texto);
                correcto = true;
            }
            else{
                System.out.println("[!] Error el DNI debe tener 8 dígitos");
            }
        }while(!correcto);

        correcto = false;
        do{
            System.out.print("Contraseña Cliente: ");
            texto = introduceDatos.introduceString();
            if(texto.length()>0 && texto.length()<=4){
                cliente.setContrasenya(texto);
                correcto = true;
            }
            else{
                System.out.println("[!] La contraseña debe tener 4 caracteres");
            }
        }while(!correcto);

        correcto = false;
        do{
            System.out.print("Teléfono Cliente: ");
            texto = introduceDatos.introduceString();
            
            if(texto.length()>0 && texto.length()==9){
                cliente.setTelefono(texto);
                correcto = true;
            }
            else{
                System.out.println("[!] El teléfono debe tener 9 dígitos");
            }
         }while(!correcto);

        correcto = false;
        do{
            System.out.print("Saldo Inicial: ");
            try{
                float sal = introduceDatos.introduceFloat();
                cliente.setSaldo(sal);
                correcto = true;
            }
            catch(Exception e){
                System.out.println("[!] Error al introducir el saldo "+e.getMessage());
            }
        }while(!correcto);

        correcto = false;
        do{
                System.out.print("Fecha Nacimiento(dd/mm/aaaa): ");
                String fechaAux = introduceDatos.introduceString();
                fecha = UtilFecha.obtenerFecha(fechaAux);
                if(Pattern.matches("\\d\\d/\\d\\d/\\d\\d\\d\\d", fechaAux)){
                    correcto = true;
                    cliente.setFechaNacimiento(fecha);
                }
                else{
                    System.out.println("[!] Error en la fecha ");
                }         
        }while(!correcto);

    

        fecha = new Date();
        cliente.setFechaAlta(fecha);
        fecha = new Date(0);
        cliente.setFechaBaja(fecha);
        cliente.setEstadoUsuario(EstadoUsuario.Alta);
        cliente.setRol(Rol.Cliente);
        boolean salir = false;

        do {
            System.out.println("¿Esta seguro de quiere dar de alta?");
            System.out.println();
            System.out.println(cliente);
            System.out.println("Seleccione una opcion");

            System.out.println("1. Si");
            System.out.println("2. No");
            int opcion = introduceDatos.introduceEntero();
            switch (opcion) {
                case 1:
                    if(!UsuarioJDBC.existeUsuarioRol(cliente.getDNI(), cliente.getRol())){
                        ClienteJDBC.insertarUsuario(cliente);
                        Ingreso ingreso = new Ingreso(new Date(), cliente.getSaldo(), "Alta inicial saldo usuario", cliente);
                        ingreso.insertarMovimiento(ingreso);
                    }
                    else{
                        System.out.println("El usuario ya existe");
                    }
                    salir = true;
                    break;
                case 2:
                    System.out.println("El usuario no se ha dado de alta");
                    salir = true;
                    break;
                default:
                    System.out.println("Opcion incorrecta");
            }
        } while (!salir);
    }

    
    /** Metodo para la consulta del cliente en cajero*/
    public void ConsultaClienteCajero() {

        System.out.println(this);

    }
 /** Hace consultas del cliente*/
    public static Cliente ConsultaClienteTienda(String dni) {

        Cliente cliente = new Cliente();

        if( dni.length() <= 8 ){
            cliente= ClienteJDBC.obtenerClientePorDni(dni);
        }
        return cliente;

    }

    /** Hace modificaciones sobre los atributos del cliente:nombre, apellidos, DNI,
     * Fecha de nacimiento, tlfno, ...
     */
    public void modificacionCliente() {
        int opcion;
        String tex;
        //EstadoUsuario estusu;
        boolean correcto = false;
        boolean salir = false;
        boolean modificado = false;
        do {
            System.out.println("Seleccione la opción que desea modificar: ");
            System.out.println("------------------------------------- ");
            System.out.println("1.- Nombre ");
            System.out.println("2.- Apellidos ");
            System.out.println("3.- DNI ");
            System.out.println("4.- Fecha de Nacimiento ");
            System.out.println("5.- Telefono ");
            System.out.println("6.- Contraseña ");
            System.out.println("7.- Estado del Usuario ");
            System.out.println("8.- Salir");
            
            opcion = introduceDatos.introduceEntero();
            System.out.println();

            switch (opcion)//accedera los usuarios
            {
                case 1:
                    correcto = false;
                    do{
                        System.out.print("Introduzca el nombre a modificar: ");
                        tex = introduceDatos.introduceString();
                        if(tex.length()!=0){
                            this.setNombre(tex);
                            System.out.println();
                            System.out.println(this);
                            modificado = true;
                            correcto = true;
                        }
                        else{
                            System.out.println("[!] El nombre no puede ser vacío");
                        }
                    }while(!correcto);
                    break;
                case 2:
                    correcto = false;
                    do{
                        System.out.print("Introduzca los apellidos que desea modificar: ");
                        tex = introduceDatos.introduceString();
                        if(tex.length()!=0){
                            this.setApellidos(tex);
                            System.out.println();
                            System.out.println(this);
                            modificado = true;
                            correcto = true;
                        }
                        else{
                            System.out.println("[!] Los apellidos no pueden ser vacío");
                        }
                    }while(!correcto);
                    break;
                case 3:
                    correcto = false;
                    do{
                        System.out.print("Introduzca el DNI a modificar: ");
                        tex = introduceDatos.introduceString();
                        if(tex.length() > 0 && tex.length()<9){
                            this.setDNI(tex);
                            System.out.println();
                            System.out.println(this);
                            modificado = true;
                            correcto = true;
                        }
                        else{
                            System.out.println("[!] El DNI debe tener 8 dígitos");
                        }
                    }while(!correcto);
                    break;
                case 4:
                    correcto = false;
                    do{
                        System.out.print("Introduzca la Fecha de Nacimiento a modificar(dd/mm/aaaa): ");
                        tex = introduceDatos.introduceString();
                        if(Pattern.matches("\\d\\d/\\d\\d/\\d\\d\\d\\d", tex)){
                            this.setFechaNacimiento(UtilFecha.obtenerFecha(tex));
                            System.out.println();
                            System.out.println(this);
                            modificado = true;
                            correcto = true;
                        }
                        else{
                            System.out.println("La fecha introducida no es correcta");
                        }
                    }while(!correcto);
                    break;
                case 5:
                    correcto = false;
                    do{
                        System.out.print("Introduzca el telefono a modificar: ");
                        tex = introduceDatos.introduceString();
                        if(tex.length()== 9){
                            this.setTelefono(tex);
                            System.out.println();
                            System.out.println(this);
                            modificado = true;
                            correcto = true;
                        }
                        else{
                            System.out.println("El teléfono debe tener 9 dígitos");
                        }
                    }while(!correcto);
                    break;
                case 6:
                    correcto = false;
                    do{
                        System.out.print("Introduzca la contraseña a modificar: ");
                        tex = introduceDatos.introduceString();
                        if(tex.length() == 4){
                            this.setContrasenya(tex);
                            System.out.println();
                            System.out.println(this);
                            modificado = true;
                            correcto = true;
                        }
                        else{
                            System.out.println("La contraseña debe tener 4 dígitos");
                        }
                    }while(!correcto);
                    break;
                //Sólo accedera el administrador/jefe
                case 7:

                    String nuevoEstado = null;
                    int i = 1;
                    for (EstadoUsuario eu : EstadoUsuario.values()) {
                        System.out.println(i + ". " + eu);
                        i++;
                    }

                    correcto = true;
                    do{
                        System.out.print("Introduzca el nuevo estado: ");
                        int pos = introduceDatos.introduceEntero();
                        if(pos != 0){
                            if (pos == 1) {
                                nuevoEstado = "Alta";
                            } else if (pos == 2) {
                                nuevoEstado = "Baja";
                            } else if (pos == 3) {
                                nuevoEstado = "Bloqueado";
                            } else {
                                System.out.println("Opción incorrecta.");
                            }
                            this.setEstadoUsuario(EstadoUsuario.valueOf(nuevoEstado));
                            System.out.println(this.getEstadoUsuario());
                            System.out.println();
                            System.out.println();
                            modificado = true;
                            correcto = true;
                        }else{
                            System.out.println("Debe elegir una opción");
                        }
                    }while(!correcto);
                    break;
                case 8:

                    if(modificado){
                        ClienteJDBC.modificarCliente(this);
                        System.out.println("La modificación se ha realizado correctamente");
                    }
                    else{
                        System.out.println("La modificación no se ha realizado");
                    }
                    
                    salir = true;
                    break;
                default:
                    System.out.println("Opción incorrecta");

            }
        } while (!salir);

    }

    public void anyadirSaldo(double sal) {

        if (sal < 0) {
            System.out.println("Error: Cantidad negativa ");
            return;
        }
        else{
            System.out.println(this);
            this.saldo += sal;
            ClienteJDBC.modificarSaldoCliente(this);
            Ingreso ingreso = new Ingreso(new Date(), sal, "Aumento de saldo", this);
            IngresoJDBC.altaIngreso(ingreso);
            System.out.println("Su actual saldo son  " + this.saldo + " euros.");
        }

    }

    public void retirarSaldo(double sal) {

        double aux = this.getSaldo() - sal;
        this.setSaldo(aux);
        System.out.println("\n");
        System.out.println(this);
        System.out.println("Saldo actual \n" + aux);
    }

    public void consultaProdAlquilado() {
        ArrayList<Alquiler> lista = AlquilerJDBC.alquilerPorCliente(this);
        
        if(!lista.isEmpty()){
            Iterator it = lista.iterator();
            while(it.hasNext()){
                Alquiler alquiler = (Alquiler)it.next();
                String cadena = alquiler.getProducto().getTitulo()+" en "+alquiler.getProducto().getTipo();
                cadena +=" Fecha de alquiler: "+UtilFecha.fechaMostrar(alquiler.getFechaInicio())+" Fecha de entrega: "+UtilFecha.fechaMostrar(alquiler.getFechaPrevistaDev());
                System.out.println(cadena);
                System.out.println("----------------------------------------------------------------------------------------------------------");
            }
        }else{
            System.out.println("No tiene ningún producto alquilado");
        }
    }

    public void consultaReservaProd() {
        ArrayList<Reserva> lista = ReservaJDBC.obtenerReserva(this);

        if(!lista.isEmpty()){
            Iterator it = lista.iterator();
            while(it.hasNext()){
                Reserva reserva = (Reserva)it.next();
                String cadena = reserva.getProducto().getTitulo()+" en "+reserva.getProducto().getTipo();
                cadena +=" Fecha de la reserva: "+UtilFecha.fechaMostrar(reserva.getFechaReserva())+"Pendiente :";
                if(reserva.getPendiente()){
                    cadena +="Sí";
                }
                else{
                    cadena +="No";
                }
                System.out.println(cadena);
                System.out.println("----------------------------------------------------------------------------------------------------------");
            }
        }
        else{
            System.out.println("Actualmente no tiene reservado ningún producto");
        }
    }

    /**
     * muestra todos los clientes que tenemos en el videoclub
     */
    //TODO Cristina: sé que no está muy bonito, pero voy a hacer la funcionalidad de otras cosas para adelantar
    public static void consultarClienteVideoClub(){
        ArrayList<Cliente> lista = ClienteJDBC.seleccionerTodosUsuarios(0);

        Iterator it = lista.iterator();
/*
        System.out.println("________________________________________________________________________________________________");
        System.out.println("|40                                      |10        |10        |10        |20                  |");
        System.out.println("|Nombre y apellidos                      |DNI       |Saldo     |Nº prod.  |Estado              |");
        System.out.println("|                                        |          |          |alquildos |                    |");
        System.out.println("================================================================================================");
 *
 */
        int i = 1;
        while(it.hasNext()){
            Cliente cliente = (Cliente)it.next();
            String cadena =i+".  NOMBRE Y APELLIDOS: "+cliente.getNombre()+" "+cliente.getApellidos();
            cadena += " DNI: "+cliente.getDNI();
            cadena += " SALDO: "+cliente.getSaldo();
            cadena += " Nº PROD. ALQ.: "+cliente.getNumProdAlqActual();
            cadena += " ESTADO: "+cliente.getEstadoUsuario();
            System.out.println(cadena);
            System.out.println("----------------------------------------------------------------------------------------------------------");
            i++;
        }
       
    }
}
